package br.com.fogas.impressora;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import br.com.fogas.utils.dialog.DialogAlert;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.Fragment;

public class ImpressoraBluetoothHelper {
	
	public interface ImpressoraBluetoothListener {
		public void impressoraPareada(boolean pareada); 
	}

	public static final int REQUEST_VISIBLE_BT = 1;
	private BluetoothAdapter bluetoothAdapter;
	private List<BluetoothDevice> dispositivosEncontrados;
	private Set<BluetoothDevice> dispositivosPareados;
	private boolean bluetoothConectadoVisivel = false;
	private boolean impressoraPareada = false;
	//private boolean impressoraPareadaLigada = false;
	private Fragment fragment; 
	private ImpressoraBluetoothListener listener;
	private ProgressDialog dialog;
	
	public ImpressoraBluetoothHelper(Fragment fragment, ImpressoraBluetoothListener listener) {
		this.fragment = fragment;
		this.listener = listener;
		this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		this.dialog = new ProgressDialog(fragment.getActivity());
	}
	
	public boolean isActivityForResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == REQUEST_VISIBLE_BT) {
			bluetoothConectadoVisivel = (bluetoothAdapter.getScanMode() == 
					BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
			
			if (bluetoothConectadoVisivel) {
				checarImpressora();
			} else {
				DialogAlert.newInstance()
				.setTitle(R.string.dialog_title_impressora)
				.setMessage(R.string.dialog_bluetooth_nao_ativo)
				.showDialog(fragment.getActivity().getSupportFragmentManager());
				impressoraPareada = false;
				finalizarVerificacao();
			}
			return true;
		} else {
			return false;
		}
	}
	
	public void checarImpressoraBluetooth() {
		iniciarBluetoothVisivel();
	}
	
	private void checarImpressora() {
		BluetoothDevice impressora = impressoraPareada();
		if(impressora != null) {
			impressoraPareada = true;
			finalizarVerificacao();
		} else {
			parearNovaImpressora();
		}
	}
	
	private void parearNovaImpressora() {
		this.dispositivosEncontrados = new ArrayList<BluetoothDevice>();
		
		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
		IntentFilter filter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);			
		IntentFilter filter3 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
		
		fragment.getActivity().registerReceiver(procurarDispositivosReceiver, filter);
		fragment.getActivity().registerReceiver(procurarDispositivosReceiver, filter2);			
		fragment.getActivity().registerReceiver(procurarDispositivosReceiver, filter3);
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		bluetoothAdapter.startDiscovery();
	}
	
	private final BroadcastReceiver procurarDispositivosReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
	        	dialog.setMessage("buscando impressora...");
	        	dialog.show();
	        } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				dispositivosEncontrados.add(device);
			} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
				dialog.dismiss();
				fragment.getActivity().unregisterReceiver(this);
	        	conectaDispositivo();
	        }
		}
	};
	
	private void conectaDispositivo() {
		BluetoothDevice impressoraDevice = null;
		for (BluetoothDevice device : dispositivosEncontrados) {
			boolean impressoraMPT = StringUtils.contains(device.getName(), "MPT");
			if(impressoraMPT) {
				impressoraDevice = device;
				break;
			}
		}
		
		if(impressoraDevice != null) {
			parearDispositivo(impressoraDevice);
		} else {
			DialogAlert.newInstance()
			.setTitle(R.string.dialog_title_impressora)
			.setCharMessage("impressora nao encontrada!")
			.showDialog(fragment.getActivity().getSupportFragmentManager());
			
			impressoraPareada = false;
			finalizarVerificacao();
		}
	}
	
	private void parearDispositivo(BluetoothDevice device) {
        try {
        	countPairReceiver = 0;
        	IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        	fragment.getActivity().registerReceiver(mPairReceiver, intent);
        	try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
        	
            Method method = device.getClass().getMethod("createBond", (Class[]) null);
            method.invoke(device, (Object[]) null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
	
	private int countPairReceiver; 
	private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {			
			if(countPairReceiver > 0) {
				String action = intent.getAction();
				if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
					final int state = intent.getIntExtra(
							BluetoothDevice.EXTRA_BOND_STATE, 
							BluetoothDevice.ERROR);
					final int prevState = intent.getIntExtra(
							BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
							BluetoothDevice.ERROR);
					
					if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
						impressoraPareada = true;
					} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED) {
						impressoraPareada = false;
					}
					fragment.getActivity().unregisterReceiver(this);
					finalizarVerificacao();
				}
			}
			countPairReceiver++;
		}
	};
	
	private BluetoothDevice impressoraPareada() {
		this.dispositivosPareados = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
		for(BluetoothDevice dispositivo: dispositivosPareados) {
			if(StringUtils.contains(dispositivo.getName(), "MPT")) {
				return dispositivo;
			}
		}
		return null;
	}

	private void iniciarBluetoothVisivel() {
		bluetoothConectadoVisivel = (bluetoothAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
		
		if(bluetoothConectadoVisivel) {
			checarImpressora();
		} else {
			Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
			fragment.startActivityForResult(intent, REQUEST_VISIBLE_BT);
		}
	}
	
	private void finalizarVerificacao() {
		if(impressoraPareada) {
			listener.impressoraPareada(true);
		} else {
			listener.impressoraPareada(false);
		}
	}
	
	/*
	private void notificarListener() {
		BluetoothDevice dispositivoPareado = impressoraPareada();
		
		BluetoothDevice dispositivoLigado = null;
		for (BluetoothDevice device : dispositivosEncontrados) {
			boolean impressoraMPT = StringUtils.contains(device.getName(), "MPT");
			if(impressoraMPT) {
				dispositivoLigado = device;
				break;
			}
		}
		
		if(dispositivoLigado != null) {
			impressoraPareadaLigada = StringUtility.equals(dispositivoPareado.getName(), dispositivoLigado.getName());
		} else {
			impressoraPareadaLigada = false;
		}
		
		if(!impressoraPareadaLigada) {
			DialogAlert.newInstance()
			.setTitle(R.string.dialog_title_impressora)
			.setCharMessage("Impressora não está ligada para impressão!")
			.showDialog(fragment.getActivity().getSupportFragmentManager());
		}
		
		listener.impressoraPareadaLigada(impressoraPareadaLigada);
		
		progressDialog.closeDialog();
	}
	
	private void verificarImpressoraLigada() {
		progressDialog
		.setMessage("Aguarde, verificando impressora está ligada...")
		.closeDialog();
		
		this.dispositivosEncontrados = new ArrayList<BluetoothDevice>();
		
		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);		
		IntentFilter filter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
		
		fragment.getActivity().registerReceiver(verificarImpressoraLigadaReceiver, filter);		
		fragment.getActivity().registerReceiver(verificarImpressoraLigadaReceiver, filter2);
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		bluetoothAdapter.startDiscovery();
	}
	
	private final BroadcastReceiver verificarImpressoraLigadaReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
	        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				dispositivosEncontrados.add(device);
			} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
				fragment.getActivity().unregisterReceiver(this);
	        	notificarListener();
	        }
		}
	};
	*/
}